﻿Imports System.Management
Imports System.ComponentModel
Imports System.Runtime.CompilerServices
Imports System.Text

<DisplayName("Network Interface")> _
Public Class NetworkInterface
    Implements INotifyPropertyChanged

    Public Event PropertyChanged As PropertyChangedEventHandler _
    Implements INotifyPropertyChanged.PropertyChanged
    Private Sub NotifyPropertyChanged(<CallerMemberName()> Optional ByVal propertyName As String = Nothing)
        RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName))
    End Sub

    Private _Interface As ManagementObject
    Public Sub New(Card As ManagementObject)

        LoadData(Card)

    End Sub

    Private Sub LoadData(Card As ManagementObject)

        For Each mo As ManagementObject In GetAdapters(Card("Caption"))
            Me._Interface = mo
            Me._NIC = Card("Caption")
            NotifyPropertyChanged("NIC")
            NotifyPropertyChanged("IP")
            NotifyPropertyChanged("SubNet")
            NotifyPropertyChanged("Gateway")
            NotifyPropertyChanged("DHCP")
            NotifyPropertyChanged("PrimaryDNS")
            NotifyPropertyChanged("SecondaryDNS")
            Exit For
        Next

    End Sub

    Private Function GetAdapters(Optional Caption As String = "") As System.Management.ManagementObjectCollection

        Dim adapters As ManagementObjectSearcher = New ManagementObjectSearcher(New ObjectQuery("SELECT * FROM Win32_NetworkAdapterConfiguration WHERE IPEnabled = TRUE and Caption='" & Caption & "'"))
        Return adapters.Get

    End Function


    Private _NIC As String
    <Category("NetworkCard")> _
    <Description("Name")> _
    <DisplayName("Name")> _
    <Browsable(False)> _
    Public ReadOnly Property NIC() As String
        Get
            Return _NIC
        End Get
    End Property

    <Category("Internet Protocol")> _
    <DisplayName("IPv4")> _
    Public ReadOnly Property IP() As String
        Get
            Return TryCast(_Interface("IPAddress"), String()).FirstOrDefault
        End Get
    End Property

    <Category("Internet Protocol")> _
    <DisplayName("IPv4 Subnet Mask")> _
    Public ReadOnly Property SubNet() As String
        Get
            Return TryCast(_Interface("IPSubnet"), String()).FirstOrDefault
        End Get
    End Property

    <Category("Internet Protocol")> _
    <DisplayName("Default Gateway")> _
    Public ReadOnly Property Gateway() As String
        Get
            Try
                Return TryCast(_Interface("DefaultIPGateway"), String()).FirstOrDefault
            Catch ex As Exception
                Return "0.0.0.0"
            End Try
        End Get
    End Property

    <Category("Internet Protocol")> _
    <DisplayName("Use DHCP")> _
    Public ReadOnly Property DHCP() As Boolean
        Get
            Return _Interface("DHCPEnabled")
        End Get
    End Property

    <Category("DNS Server")> _
    <DisplayName("Primary Dns Server")> _
    Public Property PrimaryDNS() As String
        Get

            Try
                Return TryCast(_Interface("DNSServerSearchOrder"), String()).First
            Catch ex As Exception
                Return "0.0.0.0"
            End Try

        End Get
        Set(ByVal value As String)

            Dim sb As New StringBuilder
            If TryCast(_Interface("DNSServerSearchOrder"), String()).Count > 1 Then
                sb.Append(value)
                sb.Append(",")
                sb.Append(TryCast(_Interface("DNSServerSearchOrder"), String()).Last)
            Else
                sb.Append(value)
            End If

            Dim newDNS As ManagementBaseObject = _Interface.GetMethodParameters("SetDNSServerSearchOrder")
            newDNS("DNSServerSearchOrder") = Split(sb.ToString, ",")
            Dim setDNS As ManagementBaseObject = _Interface.InvokeMethod("SetDNSServerSearchOrder", newDNS, Nothing)


            LoadData(_Interface)
            NotifyPropertyChanged()
        End Set
    End Property

    <Category("DNS Server")> _
    <DisplayName("Secondary Dns Server")> _
    Public Property SecondaryDNS() As String
        Get
            Try
                If TryCast(_Interface("DNSServerSearchOrder"), String()).Count > 1 Then
                    Return TryCast(_Interface("DNSServerSearchOrder"), String()).Last
                Else
                    Return "0.0.0.0"
                End If
            Catch ex As Exception
                Return "0.0.0.0"
            End Try

        End Get
        Set(ByVal value As String)

            If value <> String.Empty Then

                Dim sb As New StringBuilder
                sb.Append(TryCast(_Interface("DNSServerSearchOrder"), String()).First)
                sb.Append(",")
                sb.Append(value)

                Dim newDNS As ManagementBaseObject = _Interface.GetMethodParameters("SetDNSServerSearchOrder")
                newDNS("DNSServerSearchOrder") = Split(sb.ToString, ",")
                Dim setDNS As ManagementBaseObject = _Interface.InvokeMethod("SetDNSServerSearchOrder", newDNS, Nothing)

            End If

            LoadData(_Interface)
            NotifyPropertyChanged()
        End Set
    End Property

    <Category("DNS Server")> _
    <DisplayName("Get DNS from DHCP Server")> _
    <[ReadOnly](True)> _
    <Browsable(False)> _
    Public Property ClearDNS() As Boolean
        Get

            Return True

        End Get
        Set(ByVal value As Boolean)

            Dim newDNS As ManagementBaseObject = _Interface.GetMethodParameters("SetDNSServerSearchOrder")
            newDNS("DNSServerSearchOrder") = TryCast(New List(Of String), List(Of String)).ToArray
            Dim setDNS As ManagementBaseObject = _Interface.InvokeMethod("SetDNSServerSearchOrder", newDNS, Nothing)

            LoadData(_Interface)
            NotifyPropertyChanged()
        End Set
    End Property















    ''' <summary>
    ''' Set IP for the specified network card name
    ''' </summary>
    ''' <PARAM name="nicName">Caption of the network card</PARAM>
    ''' <PARAM name="IpAddresses">Comma delimited string 
    '''           containing one or more IP</PARAM>
    ''' <PARAM name="SubnetMask">Subnet mask</PARAM>
    ''' <PARAM name="Gateway">Gateway IP</PARAM>
    ''' <PARAM name="DnsSearchOrder">Comma delimited DNS IP</PARAM>
    Public Shared Sub SetIP(nicName As String, Optional IpAddresses As String = "", Optional SubnetMask As String = "", Optional Gateway As String = "", Optional DnsSearchOrder As String = "")
        Dim mc As New ManagementClass("Win32_NetworkAdapterConfiguration")
        Dim moc As ManagementObjectCollection = mc.GetInstances()

        For Each mo As ManagementObject In moc
            ' Make sure this is a IP enabled device. 
            ' Not something like memory card or VM Ware

            If mo("IPEnabled") Then
                If mo("Caption").Equals(nicName) Then

                    'Set IP Adress to Static and SubnetMask
                    If IpAddresses <> String.Empty Then
                        Dim newIP As ManagementBaseObject = mo.GetMethodParameters("EnableStatic")
                        newIP("IPAddress") = IpAddresses.Split(","c)
                        newIP("SubnetMask") = New String() {SubnetMask}
                        Dim setIP__1 As ManagementBaseObject = mo.InvokeMethod("EnableStatic", newIP, Nothing)
                    End If

                    'Set Gateway and Gateway Metric
                    If Gateway <> String.Empty Then
                        Dim newGate As ManagementBaseObject = mo.GetMethodParameters("SetGateways")
                        newGate("DefaultIPGateway") = New String() {Gateway}
                        newGate("GatewayCostMetric") = New Integer() {1}
                        Dim setGateways As ManagementBaseObject = mo.InvokeMethod("SetGateways", newGate, Nothing)
                    End If

                    'Set DNS Server IP
                    If DnsSearchOrder <> String.Empty Then
                        Dim newDNS As ManagementBaseObject = mo.GetMethodParameters("SetDNSServerSearchOrder")
                        newDNS("DNSServerSearchOrder") = DnsSearchOrder.Split(","c)
                        Dim setDNS As ManagementBaseObject = mo.InvokeMethod("SetDNSServerSearchOrder", newDNS, Nothing)
                    End If


                    Exit For
                End If
            End If
        Next
    End Sub


End Class

